#include "tcp_socket_holder.h"

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <errno.h>


namespace tinySrv
{

  TCPSocketHolder::TCPSocketHolder(bool nonBlocking)
    : Handle(socket(AF_INET, SOCK_STREAM | (nonBlocking ? SOCK_NONBLOCK : 0), 0))
  {
    if (Handle == -1)
      throw TCPSocketHolderException("Can't create socket", errno);
    int on = 1;
    if (setsockopt(Handle, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) 
    {
      close(Handle);
      throw TCPSocketHolderException("Can't reuse socket", errno);
    }
  }
  
  TCPSocketHolder::TCPSocketHolder(int handle)
    : Handle(handle)
  {
    if (Handle == -1)
      throw TCPSocketHolderException("Bad socket");
  }
  
  TCPSocketHolder::~TCPSocketHolder()
  {
    if (Handle != -1)
      close(Handle);
  }
  
  int TCPSocketHolder::GetSocket() const
  {
    return Handle;
  }
  
  int TCPSocketHolder::Detach()
  {
    int Ret = Handle;
    Handle = -1;
    return Ret;
  }
  
  void TCPSocketHolder::SetNoDelay(bool useDelay)
  {
    int On = useDelay ? 0 : 1;
    if (setsockopt(Handle, IPPROTO_TCP, TCP_NODELAY, &On, sizeof(On)) == -1)
      throw TCPSocketHolderException("Failed to set NoDelay option");
  }

}
